<?php


namespace App\Service\PayApi;


use _HumbugBox373c0874430e\Nette\Neon\Exception;
use App\Model\Dao\MchAccountDao;
use App\Model\Dao\MchConfigDao;
use App\Model\Dao\MchInfoDao;
use App\Model\Dao\SysCardTypeInfoDao;
use App\Model\Dao\TradeOrderBaseDao;
use App\Model\Dao\TradeOrderDetailDao;
use App\Model\Dao\TradeOrderReceiveDao;
use App\Model\Enum\PayTypeEnum;
use App\Model\Enum\StatusEnum;
use App\Service\MchAccountStatusService;
use App\Service\MchConfigStatusService;
use App\Service\MchInfoStatusService;
use App\Utils\CustomUtils;
use App\Utils\StringUtils;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Utils\Arr;

/**
 * Class TradeOrderService
 * 交易支付订单处理
 *
 * @package App\Service\PayApi
 */
class TradeOrderService {

    /**
     * @var MchInfoDao
     * @Inject()
     */
    protected $MchInfoDao;

    /**
     * @var MchConfigDao
     * @Inject()
     */
    protected $MchConfigDao;

    /**
     * @var MchAccountDao
     * @Inject()
     */
    protected $MchAccountDao;

    /**
     * @var TradeOrderBaseDao
     * @Inject()
     */
    protected $TradeOrderBaseDao;

    /**
     * @var TradeOrderDetailDao
     * @Inject()
     */
    protected $TradeOrderDetailDao;

    /**
     * @var TradeOrderReceiveDao
     * @Inject()
     */
    protected $TradeOrderReceiveDao;

    /**
     * 创建预支付订单
     *
     * @param $params
     *
     * @return array
     * @throws \Throwable
     */
    public function createPreOrder ($params) {

        Db::beginTransaction();

        try {

            // 交易详情
            $orderDetail = $this->_createOrderDetail($params);

            // 交易跟踪
            $orderBase = $this->_createOrderBase($params, $orderDetail);

        } catch (\Throwable $e) {
            Db::rollBack();
            throw $e;
        }

        Db::commit();

        $data = [
            'orderDetail' => $orderDetail,
            'orderBase'   => $orderBase,
        ];

        return $data;
    }

    /**
     * 获取预支付订单
     *
     * @param $params
     *
     * @return array
     */
    public function getPreOrder ($params) {

        $order   = $params['order'];
        $tradeNo = $order['tradeNo'];

        $orderDetail = $this->TradeOrderDetailDao->getWhere(['tradeNo' => $tradeNo]);

        if (!$orderDetail) {
            throw new \Exception(trans('pay.order.not_found'));
        }

        $orderBase = $this->TradeOrderBaseDao->getWhere(['orderId' => $orderDetail['id']]);

        $data = [
            'orderDetail' => $orderDetail,
            'orderBase'   => $orderBase,
        ];

        return $data;
    }

    public function setOrderReceive ($payType, $orderId, $update) {

        $orderReceive = $this->TradeOrderReceiveDao->getWhere(['orderId' => $orderId]);

        switch ($payType) {
            case PayTypeEnum::CREDIT:

                $update = Arr::only($update, [

                    // 订单信息
                    'tradeNo',
                    'mchId',
                    'mchNo',

                    // 信用卡信息
                    'cardType',
                    'cardNo',
                    'cardCvv',
                    'cardExpireY',
                    'cardExpireM',

                    // 持卡人信息
                    'cardCountry',
                    'cardState',
                    'cardCity',
                    'cardAddress',
                    'cardFullPhone',
                    'cardEmail',
                    'cardFullName',
                    'cardZipCode',

                    // 收货人信息
                    'grCountry',
                    'grState',
                    'grCity',
                    'grAddress',
                    'grZipCode',
                    'grEmail',
                    'grPhoneNumber',
                    'grPerName',

                    'goodsInfo',
                    'bankBillUrl',

                    'status',
                ]);

                if (!$orderReceive) {
                    $update['id']      = CustomUtils::createUUID();
                    $update['orderId'] = $orderId;

                    $this->TradeOrderReceiveDao->insert($update);
                }
                else {
                    $this->TradeOrderReceiveDao->update($orderReceive['id'], $update);
                }

                $orderReceive = $this->TradeOrderReceiveDao->getWhere(['orderId' => $orderId]);

                break;
            default:
                throw new \Exception(trans('pay.type.not_support'));
                break;
        }

        return $orderReceive;
    }

    public function getOrderDetail ($id) {
        return $this->TradeOrderDetailDao->get($id);
    }

    /**
     * @param      $tradeNo
     * @param      $code
     * @param      $message
     * @param bool $isBankHandle
     */
    public function setOrderBaseFail ($tradeNo, $code, $message, $isBankHandle = false) {

        // TODO::formatRespMsg
        // $formatRet = $this->CommonService->formatRespMsg($code, $message, $isBankHandle);
        // $formatRet = ['message' => 'TODO::formatRespMsg'];
        $formatRet = ['message' => $message];

        $this->TradeOrderBaseDao->updateWhere(['tradeNo' => $tradeNo], [
            'respCode'      => $code,
            'respMsg'       => $message,
            'formatRespMsg' => $formatRet['message'],
        ]);
    }


    /**
     * 添加数据:交易信息详情表
     *
     * @param $params
     *
     * @return mixed
     */
    private function _createOrderDetail ($params) {

        $now = time();

        // 基础信息
        $orderDetail = [
            'id'      => CustomUtils::createUUID(),
            'tradeNo' => CustomUtils::createTradeNo(),

            'mchId'  => Arr::get($params, 'mch.mchInfo.id'),
            'mchNo'  => Arr::get($params, 'mch.mchInfo.mchNo'),
            'mchUrl' => Arr::get($params, 'mch.mchUrl'),

            'orderNo'          => Arr::get($params, 'order.orderNo'),
            'mchTransCurrency' => Arr::get($params, 'order.mchTransCurrency'),
            'mchTransAmount'   => Arr::get($params, 'order.mchTransAmount'),
        ];

        // 状态和环境
        $orderDetail = array_merge($orderDetail, [
            // 支付类型
            'channelType'  => Arr::get($params, 'payType'),
            // 交易日期
            'mchTransTime' => $now,
            // 支付ip
            'ipAddress'    => Arr::get($params, 'environment.ipAddress'),
            // 浏览器信息
            'webInfo'      => Arr::get($params, 'environment.webInfo'),

            // 是否结算
            'isSettle'     => 0,
            'isRefund'     => 0,
            'isDis'        => 0,
            'isFrozen'     => 0,
            'isThaw'       => 0,

            // 扩展信息
            'attach'       => Arr::get($params, 'order.attach'),
            // 交易状态
            'transStatus'  => 0,
            // 可用状态
            'status'       => StatusEnum::ON,
        ]);

        $this->TradeOrderDetailDao->insert($orderDetail);

        $orderDetail = $this->TradeOrderDetailDao->get($orderDetail['id']);

        return $orderDetail;
    }

    /**
     * 新增订单支付信息,收货信息
     * TODO 支持其他支付类型
     *
     * @param $params
     * @param $orderDetail
     *
     * @return mixed
     */
    private function _createOrderReceive ($params, $orderDetail) {

        $order      = $params['order'];
        $payType    = $params['payType'];
        $payAccount = $params['payAccount'];

        // 基础信息
        $receive = [
            'id' => CustomUtils::createUUID(),

            'mchId'   => $params['mchId'],
            'mchNo'   => $params['mchNo'],
            'orderId' => $orderDetail['id'],
            'tradeNo' => $orderDetail['tradeNo'],
            'status'  => StatusEnum::ON,
        ];

        // 持卡人信息
        switch ($payType) {

            case PayTypeEnum::CREDIT:

                $receive = array_merge($receive, [
                    'cardType'      => $payAccount['cardType'],
                    'cardNo'        => $payAccount['cardNo'],
                    'cardCvv'       => '',
                    'cardExpireY'   => '',
                    'cardExpireM'   => '',

                    // 卡信息 --->国家
                    'cardCountry'   => $payAccount['cardCountry'],
                    // 卡信息 --->州/省
                    'cardState'     => $payAccount['cardState'],
                    // 卡信息 --->市
                    'cardCity'      => $payAccount['cardCity'],
                    // 卡信息 --->详细地址
                    'cardAddress'   => $payAccount['cardAddress'],
                    // 持卡人电话
                    'cardFullPhone' => $payAccount['cardFullPhone'],
                    // 持卡人邮箱
                    'cardEmail'     => $payAccount['cardEmail'],
                    // 持卡人姓名
                    'cardFullName'  => $payAccount['cardFullName'],
                    // 卡信息 --->邮编
                    'cardZipCode'   => $payAccount['cardZipCode'],
                ]);

                // 收货人信息
                $receive = array_merge($receive, [
                    // 收货信息 --->国家
                    'grCountry'     => $order['grCountry'],
                    // 收货信息 --->州/省
                    'grState'       => $order['grState'],
                    // 收货信息 --->市
                    'grCity'        => $order['grCity'],
                    // 收货信息 --->详细地址
                    'grAddress'     => $order['grAddress'],
                    // 收货信息 --->邮编
                    'grZipCode'     => $order['grZipCode'],
                    // 收货信息 --->邮箱
                    'grEmail'       => $order['grEmail'],
                    // 收获人电话
                    'grPhoneNumber' => $order['grPhoneNumber'],
                    // 收获人名称
                    'grPerName'     => $order['grPerName'],
                    // 商品信息
                    'goodsInfo'     => $order['goodsInfo'],
                ]);

                break;
        }

        switch ($payType) {
            case PayTypeEnum::CREDIT:
                $this->TradeOrderReceiveDao->insert($receive);
                $receive = $this->TradeOrderReceiveDao->get($receive['id']);
                break;
            default:
                $receive = null;
                break;
        }

        return $receive;
    }

    /**
     * 新增:交易跟踪表
     *
     * @param $params
     * @param $orderDetail
     *
     * @return mixed
     */
    private function _createOrderBase ($params, $orderDetail) {

        $base = [
            'id' => CustomUtils::createUUID(),

            'orderId' => $orderDetail['id'],
            'tradeNo' => $orderDetail['tradeNo'],

            'mchId' => Arr::get($params, 'mch.mchInfo.id'),
            'mchNo' => Arr::get($params, 'mch.mchInfo.mchNo'),

            'submitUrl'    => Arr::get($params, 'environment.submitUrl'),
            'returnUrl'    => Arr::get($params, 'after.returnUrl'),
            'mchNotifyUrl' => Arr::get($params, 'after.mchNotifyUrl'),

            'description' => '接收商户网站交易数据',
            'respCode'    => '',
            'respMsg'     => '',
            'status'      => StatusEnum::ON,
        ];

        $this->TradeOrderBaseDao->insert($base);

        $base = $this->TradeOrderBaseDao->get($base['id']);

        return $base;
    }

    private function _createOrderDebit ($params) {
        // todo 储蓄卡
    }


    private function _createOrderWechatPay ($params) {
        // todo 微信
    }

    private function _createOrderAlipay ($params) {
        // todo 支付宝
    }


}
